<?php

/**
 * Description of Application_Model_JsController
 *
 * @author Jean Brito
 */
abstract class Application_Model_JsController extends Application_Model_Fix {

	const DIR='js/app/controller';
	const EXTENSAO='.js';


	static public function getFileController($dirName){
		$fd=explode('/',strtolower(trim(self::DIR.'/'.str_replace(".","/",$dirName),"/")));
		$fdir="./";
		foreach($fd as $d=>$dir)if($d<(count($fd)-1)){
			$fdir.=$dir;
			if(!is_dir($fdir)){
				mkdir($fdir);
			}
			$fdir.="/";
		}
		$file=$fdir.$dir.self::EXTENSAO;
		return $file;
	}


	static public function decodeControle($content){
		$str=$content;
		$data=Array(
				'functions'=>array()
		);

		$chave=0;$pos=array();
		$param=1;$posParam=0;$function="";$functionPos=0;$parenteses=0;$comentarioInicio=0;$comentario="";
		for($i=0;$i<strlen($str);$i++){
			$chr=$str[$i];
			if($chr=="{"){
				$chave++;
				$pos[$chave]['inicio']=$i;
				if($chave==1)$posParam=$i+1;
			}
			if($chave==1){
				if(substr($str,$i,3)=="/**"){
					$comentarioInicio=$i;
					$comentario="";
				}
				if($comentarioInicio&&substr($str,$i,2)=="*/"){
					$comentario=substr($str,$comentarioInicio,$i-$comentarioInicio+2);
					$comentarioInicio=0;
					$posParam=$i+2;
				}
				if(!$comentarioInicio){
					if($chr==":"){
						if(substr($str,$i+2,9)=="function("){
							$function=str_replace("\n","",str_replace("\t","",str_replace(" ","",substr($str,$posParam,$i-$posParam-1))));
							$functionPos=$posParam;
							$parenteses=1;
							//print "f[$function $functionPos $i]<br>";
							//print substr($str,$functionPos,$i-$functionPos)."<br>";
						}
					}
					if($parenteses&&$chr==")")$parenteses=0;
					if($chr==",")if(!$parenteses){
						if($functionPos){
							if($comentario!=''){
								$data['functions'][$function]['comentario']=$comentario;
								$rowcomentario=explode('@',trim(str_replace("*","",str_replace("/**","",str_replace("*/","",$comentario)))));
								if(count($rowcomentario))foreach($rowcomentario as $fieldcomentario){
									$field=trim(str_replace("\n","",str_replace("\t","",substr($fieldcomentario,0,strpos($fieldcomentario," ")))));
									$value=substr($fieldcomentario,strpos($fieldcomentario," "),strlen($fieldcomentario));
									$data['functions'][$function][$field]=$value;
								}
							}

							$data['functions'][$function]['name']=$function;
							$data['functions'][$function]['script']=substr($str,$functionPos,$i-$functionPos+1);
							$comentario="";
						}
						$functionPos=0;
						$function="";
						$param++;
						$posParam=$i+1;
					}
				}
			}
			if($chr=="}"){
				$chave--;
			}
		}
		return $data;
	}

	static public function getFilesControllers($dirName=self::DIR){
		$fd=explode('/',strtolower(trim(str_replace(".","/",$dirName),"/")));
		$fdir="./";
		foreach($fd as $d=>$dir)if($d<(count($fd))){
			$fdir.=$dir;
			if(!is_dir($fdir)){
				mkdir($fdir);
			}
			$fdir.="/";
		}
		$files=array();
		foreach(scandir($fdir) as $ndir){
			if($ndir!="."&&$ndir!=".."){
				if(is_dir($fdir.$ndir)){
					foreach(self::getFilesControllers($fdir.$ndir) as $sndir){
						$files[]=$sndir;
					}
				}else{
					$files[]=$fdir.$ndir;
				}
			}
		}
		return $files;
	}

	static public function decodeFile($file){
		$data=array();
		$controllerName=str_replace("/",".",str_replace('./'.self::DIR.'/','',str_replace(self::EXTENSAO,'',$file)));
		if(file_exists($file)){
			$file_content=file_get_contents($file);
		}else{
			$file_content="Ext.define('AgenteNET.controller.$controllerName',{\n";
			$file_content.="    extend : 'Ext.app.Controller',\n";
			$file_content.="    init : function(){\n";
			$file_content.="    },\n";
			$file_content.="});\n";
		}
		$data['content']=$file_content;
		$data['functions']=array();
		$content=$file_content; //substr($file_content,strpos($file_content,"{\n"),strrpos($file_content,"});\n")+1-strpos($file_content,"{\n"));
		$decodeRow=self::decodeControle($content);
		foreach($decodeRow['functions'] as $key=>$item){
			$data['functions'][$key]=$item;
		}
		return $data;
	}

	static public function read($model){
		$data=array();
		foreach(self::getFilesControllers() as $file){
			$fileData=self::decodeFile($file);
			foreach($fileData['functions'] as $key=>$values){
				$row=array();
				$row['controle']=str_replace("/",".",str_replace("./".self::DIR."/","",str_replace(self::EXTENSAO,"",$file)));
				$row['funcao']=$key;
				$row['id']=str_replace(".","",$row['controle'].".".$row['funcao']);
				$row['rotulo']=$row['funcao'];
				$row['titulo']=$row['funcao'];
				$row['situacao']='A';
				$row['chamadas']=array();
				$row['funcoes']=array();
				if(count($values)){
					foreach($model->getFields() as $field){
						if(isset($values[$field['name']]))
							$row[$field['name']]=$model->{$field['name']}->getSqlValue($values);
					}
					if(count($row))if(isset($row['nome']))
						$data[]=$row;
				}
			}
		}
		$model->setData($data);
		return $data;
	}

	static public function write($model,$result,$operacao='gravar'){
		if(count($result['data'])){
			$params=array();
			$row=$result['data'];
			$controle=$row['controle'];
			if($controle){
				$file=self::getFileController($controle);
				$dataFile=self::decodeFile($file);
				$update="";$insert=0;
				foreach($dataFile['functions'] as $key=>$rowFile){
					if($key==$row['funcao']){
						foreach($row as $p=>$v)$rowFile[$p]=$v;
						$update=$key;
					}
				}
				if($update==""){
					$dataFile['functions'][$row['funcao']]=$row;
					$script="\n".
							"    ".$row['funcao']." : function(el){ \n".
							"        console.log('Fazer o corpo da funcao');\n".
							"    },\n";
					$dataFile['functions'][$row['funcao']]['script']=$script;
					$update=$row['funcao'];$insert=1;
				}

				$content=$dataFile['content'];
				$comentario="";
				if($operacao=="delete"){
					//$content=str_replace($dataFile['functions'][$update]['comentario'],"",$content);
					$content=str_replace($dataFile['functions'][$update]['script'],"\n    /** \n    @excluido \n".$dataFile['functions'][$update]['script']."\n    */\n",$content);
				}else{
					if($update!=""){
						$comentario="/**\n";
						foreach($model->getFields() as $field)if($field['name']!='controle'&&$field['name']!='funcao'){
							if(isset($result['data'][$field['name']]))$comentario.="    * @".$field['name']." ".str_replace("'","",str_replace("<br>","\n",$model->{$field['name']}->getSqlSet($result['data'][$field['name']])))."\n";
						}
						$comentario.="    */";

						if($insert){
							$content=substr($content,0,strrpos($content,"});"));
							$content.="    ".$comentario;
							$content.="    ".$dataFile['functions'][$update]['script']."\n";
							$content.="});";
						}else{
							if($dataFile['functions'][$update]['comentario']!=''){
								$content=str_replace($dataFile['functions'][$update]['comentario'],$comentario,$content);
							}else{
								$content=str_replace($dataFile['functions'][$update]['script'],"\n    ".$comentario.$dataFile['functions'][$update]['script'],$content);
							}
						}
					}
				}
				
				$fo=fopen($file,'w');
				fwrite($fo,$content);
				fclose($fo);
			}
		}
	}

	static public function index($model, $filter = null, $start = null, $limit = null, $sort = null) {
		self::read($model);
		return parent::index($model, $filter, $start, $limit, $sort);
	}

	static public function get($model, $id) {
		self::read($model);
		return parent::get($model, $id);
	}

	static public function post($model,$params) {
		$result=parent::post($model,$params);
		self::write($model,$result);
		return $result;
	}

	static public function delete($model,$id) {
		self::read($model);
		$record=parent::get($model,$id);
		self::write($model,$record,"delete");
		$result=parent::delete($model,$id);
		return $result;
	}

	static public function put($model,$id, $params) {
		self::read($model);
		$result=parent::put($model,$id,$params);
		self::write($model,$result);
		return $result;
	}

}